home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
MATHS
/
PARI
/
PARI2
/
pari
/
c
/
gen2
< prev
next >
Wrap
Text File
|
1991-11-28
|
53KB
|
2,121 lines
/********************************************************************/
/********************************************************************/
/** **/
/** +++++++++++++++++++++++++++++++ **/
/** + + **/
/** + OPERATIONS GENERIQUES + **/
/** + (deuxieme partie) + **/
/** + + **/
/** + copyright Babe Cool + **/
/** + + **/
/** +++++++++++++++++++++++++++++++ **/
/** **/
/** **/
/********************************************************************/
/********************************************************************/
# include "genpari.h"
/*******************************************************************/
/*******************************************************************/
/* */
/* LISTE DES TYPES GENERIQUES */
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* */
/* 1 :entier long [ cod1 ] [ cod2 ] [ man1 ] ... [ manl ] */
/* 2 :reel [ cod1 ] [ cod2 ] [ man1 ] ... [ manl ] */
/* 3 :entier modulo [ code ] [ mod ] [ entier modulo ] */
/* 4 :fraction [ code ] [ num. ] [ den. ] */
/* 5 :nfraction [ code ] [ num. ] [ den. ] */
/* 6 :complexe [ code ] [ reel ] [ imag ] */
/* 7 :p-adique [ cod1 ] [ cod2 ] [ p ] [ p^r ] [ entier] */
/* 8 :quadrat [ cod1 ] [ mod ] [ reel ] [ imag ] */
/* 9 :poly mod [ code ] [ mod ] [ polynome mod ] */
/* --------------------------------------------------------------- */
/* 10 :polynome [ cod1 ] [ cod2 ] [ man1 ] ... [ manl ] */
/* 11 :serie [ cod1 ] [ cod2 ] [ man1 ] ... [ manl ] */
/* 13 :fr.rat [ code ] [ num. ] [ den. ] */
/* 14 :n.fr.rat [ code ] [ num. ] [ den. ] */
/* 15 :formqre [ code ] [ a ] [ b ] [ c ] [ del ] */
/* 16 :formqim [ code ] [ a ] [ b ] [ c ] */
/* 17 :vecteur ligne [ code ] [ x1 ] ... [ xl ] */
/* 18 :vecteur colonne [ code ] [ x1 ] ... [ xl ] */
/* 19 :matrice [ code ] [ col1 ] ... [ coll ] */
/* */
/*******************************************************************/
/*******************************************************************/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* OPERATIONS PAR VALEUR */
/* */
/* parametres : f pointe sur la fonction appelee; */
/* x,y,... ,z pointent sur des GEN; */
/* le dernier parametre recoit le resultat de */
/* l'operation . */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void gop0z(f,x)
GEN (*f)(),x;
{
long avmacourant;
GEN p1;
avmacourant=avma;
p1=(*f)();gaffect(p1,x);
avma=avmacourant;
}
/* operation a un parametre */
void gop1z(f,x,y)
GEN (*f)(),x,y;
{
long avmacourant;
GEN p1;
avmacourant=avma;p1=(*f)(x);gaffect(p1,y);
avma=avmacourant;
}
/* operation a deux parametres */
void gop2z(f,x,y,z)
GEN (*f)(),x,y,z;
{
long avmacourant;
GEN p1;
avmacourant=avma;p1=(*f)(x,y);gaffect(p1,z);
avma=avmacourant;
}
void gops2gsz(f,x,s,z)
GEN (*f)(),x,z;
long s;
{
long avmacourant;
GEN p1;
avmacourant=avma;p1=(*f)(x,s);gaffect(p1,z);
avma=avmacourant;
}
void gops2sgz(f,s,y,z)
GEN (*f)(),y,z;
long s;
{
long avmacourant;
GEN p1;
avmacourant=avma;p1=(*f)(s,y);gaffect(p1,z);
avma=avmacourant;
}
void gops2ssz(f,s,y,z)
GEN (*f)(),z;
long s,y;
{
long avmacourant;
GEN p1;
avmacourant=avma;p1=(*f)(s,y);gaffect(p1,z);
avma=avmacourant;
}
/* operation a trois parametres */
void gop3z(f,x,y,z,t)
GEN (*f)(),x,y,z,t;
{
long avmacourant;
GEN p1;
avmacourant=avma;p1=(*f)(x,y,z);gaffect(p1,t);
avma=avmacourant;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* OPERATIONS AVEC DES ENTIERS COURTS */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN gopsg2(f,s,y)
long s;
GEN (*f)(),y;
{
long court[3];
court[0] = 0x1010003;
affsi(s,court);return (*f)(court,y);
}
GEN gopgs2(f,y,s)
long s;
GEN (*f)(),y;
{
long court[3];
court[0] = 0x1010003;
affsi(s,court);return (*f)(y,court);
}
long opgs2(f,y,s)
long s,(*f)();
GEN y;
{
long court[3];
court[0] = 0x1010003;
affsi(s,court);return (*f)(y,court);
}
void gops1z(f,s,y)
long s;
GEN (*f)(),y;
{
long av=avma; gaffect((*f)(s),y); avma=av;
}
void gopsg2z(f,s,y,z)
long s;
GEN (*f)(),y,z;
{
long av, court[3];
court[0] = 0x1010003;
affsi(s,court);av=avma;
gaffect((*f)(court,y),z);avma=av;
}
void gopgs2z(f,y,s,z)
long s;
GEN (*f)(),y,z;
{
long av, court[3];
court[0] = 0x1010003;
affsi(s,court);av=avma;
gaffect((*f)(y,court),z);avma=av;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* CREATION D'UN P-ADIQUE */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN cgetp(x)
GEN x;
{
GEN y;
y=cgetg(5,7);
y[2] = x[2]; y[3] = lcopy(x[3]);
setprecp(y, precp(x)); y[4] = lgeti(lg(x[3]));
return y;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* CLONE ET COPIE */
/* */
/* Cree la replique exacte d'un GEN existant */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN gcopy(x)
GEN x;
{
long tx=typ(x),lx=lg(x),i;
GEN y;
y=cgetg(lx,tx);
if(tx<=2)
for(i=1;i<lx;i++) y[i]=x[i];
else
{
if(tx==10) lx=lgef(x);
if((tx==11)&&gcmp0(x)) lx=2;
for(i=1;i<lontyp[tx];i++)
y[i]=x[i];
for(i=lontyp[tx];i<lontyp2[tx];i++)
y[i]=copyifstack(x[i]);
for(i=lontyp2[tx];i<lx;i++)
y[i]=lcopy(x[i]);
}
return y;
}
GEN forcecopy(x)
GEN x;
{
long tx=typ(x),lx=lg(x),i;
GEN y;
y=cgetg(lx,tx);
if(tx<=2)
for(i=1;i<lx;i++) y[i]=x[i];
else
{
if(tx==10) lx=lgef(x);
if((tx==11)&&gcmp0(x)) lx=2;
for(i=1;i<lontyp[tx];i++)
y[i]=x[i];
for(i=lontyp[tx];i<lontyp2[tx];i++)
y[i]=(long)forcecopy(x[i]);
for(i=lontyp2[tx];i<lx;i++)
y[i]=(long)forcecopy(x[i]);
}
return y;
}
long taille(x)
GEN x;
{
long i, n, lx = lg(x), tx = typ(x);
if (tx <= 2) return (tx == 1) ? lgef(x) : lx;
if ((tx == 11) && gcmp0(x)) return 2;
if (tx == 10) lx = lgef(x);
n = lx;
for(i = lontyp[tx]; i < lx; i++) n += taille(x[i]);
return n;
}
GEN brutcopy(x, y)
GEN x, y;
{
long i, lx, tx = typ(x);
GEN z;
lx = ((tx == 1) || (tx == 10)) ? lgef(x) : lg(x);
if (tx <= 2)
for(i = 0; i < lx; i++) y[i] = x[i];
else
{
if ((tx == 11) && gcmp0(x)) lx = 2;
z = y + lx;
for(i = 0; i < lontyp[tx]; i++) y[i] = x[i];
for(i = lontyp[tx]; i < lx; i++)
{
y[i] = (long)brutcopy(x[i], z);
z += taille(x[i]);
}
}
setlg(y,lx);
return y;
}
GEN gclone(x)
GEN x;
{
GEN y = newbloc(taille(x));
return brutcopy(x, y);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* GREFFE */
/* */
/* Greffe d'une serie sur un polynome */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN greffe(x,l)
long l;
GEN x;
{
long i,e,k;
GEN y;
if (typ(x)!=10) err(grefer1);
else
{
y=cgetg(l,11);
if (gcmp0(x))
{
y[1]=0x7ffe +l;
for (i=2;i<l;y[i]=x[2],i++);
}
else
{
e=gval(x,varn(x));y[1]=0x1008000+e;
k=lgef(x)-e-1;
if (k<l)
{
for (i=2;i<=k;y[i]=x[i+e],i++);
for (i=k+1;i<l;y[i]=zero,i++);
}
else
for (i=2;i<l;y[i]=x[i+e],i++);
}
}
setvarn(y,varn(x));return y;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* CONVERSION GEN <-->REEL DU C */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
double rtodbl(x)
GEN x;
{
double y,ma,co=32.0;
long ex,s=signe(x);
if((!s)||((ex=expo(x))< -1023)) return 0.0;
if(ex>=0x3ff) err(rtodber);
ma=(ulong)x[2]+(ulong)x[3]/exp2(co);
y=exp2(ex+1-co);
return (s<0) ? -y*ma : y*ma;
}
GEN dbltor(x)
double x;
{
GEN z;
double co=32.0;
ulong y;
long ex;
int n;
if(x==0) {z=cgetr(3);z[2]=0;z[1]=0x800000-308;return z;}
z=cgetr(4);if(x<0) {setsigne(z,-1);x= -x;} else setsigne(z,1);
ex=floor(log2(x));setexpo(z,ex);x=x*exp2(-ex+co-1);y=x;x-=y;z[2]=y;
y=exp2(co)*x;z[3]=y;
if(!(z[2]&(1<<31)))
{
n=bfffo(z[2]);z[2]=shiftl(z[2],n);z[3]=shiftl(z[3],n);
z[2]+=hiremainder;setexpo(z,expo(z)-n);
}
return z;
}
double gtodouble(x)
GEN x;
{
GEN x1;
long t=typ(x);
static long reel4[4]={0x2010004,0,0,0};
if (t==2) x1=x;
else gaffect(x,x1=(GEN)reel4);
return rtodbl(x1);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* CONVERSION GEN-->LONG DU C */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
long gtolong(x)
GEN x;
{
long y,tx,av;
GEN p1,p2;
tx=typ(x);av=avma;
switch(tx)
{
case 1 : y=itos(x);break;
case 4 :
case 5 : p1=dvmdii(x[1],x[2],&p2);
if (!cmpis(p2,0))
{
y=signe(x)*itos(p1);break;
}
else err(gtolger);
case 6 : if (gcmp0(x[2])) y=gtolong(x[1]);
else err(gtolger);
break;
case 8 : if (gcmp0(x[3])) y=gtolong(x[2]);
else err(gtolger);
break;
default: err(gtolger);
}
avma=av;
return y;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* COMPARAISON A ZERO */
/* */
/* x pointe sur un GEN;la fonction renvoie 1 si le */
/* GEN est nul,0 sinon . */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
gcmp0(x)
GEN x;
{
long typy=typ(x),l,i;
switch(typy)
{
case 1 :
case 2 :
case 10:
case 11: return !signe(x);
case 3 :
case 9 : return gcmp0(x[2]);
case 4 :
case 5 : return !signe(x[1]);
case 13:
case 14: return gcmp0(x[1]);
case 6 : return gcmp0(x[1])&&gcmp0(x[2]);
case 8 : return gcmp0(x[2])&&gcmp0(x[3]);
case 7 : return !signe(x[4]);
case 15:
case 16:
case 17:
case 18:
case 19: l=lg(x);i=1;
while ((i<l)&&gcmp0(x[i])) i++;
return i==l;
default: err(gcmper);
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* COMPARAISONS A 1 et -1 */
/* */
/* x pointe sur un GEN;la fonction renvoie 1 si le */
/* GEN est l'entier 1 (resp.-1),0 sinon . */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
gcmp1(x)
GEN x;
{
long typy=typ(x),l,y;
GEN p1;
switch(typy)
{
case 1 : return (lgef(x)==3)&&(signe(x)==1)&&(mant(x,1)==1);
case 2 : l=avma;p1=subrs(x,1);
y=(!signe(p1));avma=l;
return y;
case 3 :
case 9 : return gcmp1(x[2]);
case 4 : return gcmp1(x[1])&&gcmp1(x[2]);
case 5 : return !(cmpii(x[1],x[2]));
case 6 : return gcmp1(x[1])&&gcmp0(x[2]);
case 8 : return gcmp1(x[2])&&gcmp0(x[3]);
case 7 : return !valp(x)&&gcmp1(x[4]);
case 10 : return (lgef(x)==3)&&gcmp1(x[2]);
default: return 0;
}
}
gcmp_1(x)
GEN x;
{
long typy=typ(x),l,y;
GEN p1;
switch(typy)
{
case 1 : return (lgef(x)==3)&&(signe(x)== -1)&&(mant(x,1)==1);
case 2 : l=avma;p1=addsr(1,x);
y=(!signe(p1));avma=l;
return y;
case 3 : l=avma;p1=addsi(1,x[2]);
y=cmpii(p1,x[1]);avma=l;
return !y;
case 4 :
case 5 : l=avma;p1=addii(x[1],x[2]);
y=signe(p1);avma=l;
return !y;
case 6 : return gcmp_1(x[1])&&gcmp0(x[2]);
case 8 : return gcmp_1(x[2])&&gcmp0(x[3]);
case 7 : l=avma;p1=addsi(1,x[4]);
y=cmpii(p1,x[3]);avma=l;
return !y;
case 9 : l=avma;p1=gaddsg(1,x[2]);
y=(!gegal(p1,x[1]))&&(signe(p1));avma=l;
return !y;
case 10 : return (lgef(x)==3)&&gcmp_1(x[2]);
default: return 0;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* COMPARAISON SIGNEE */
/* */
/* rend le signe de x-y si ceci a un sens, */
/* sinon erreur. */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
long gcmp(x,y)
GEN x,y;
{
long tx,ty,f,avmacourant;
tx=typ(x);ty=typ(y);
if ((tx>5)||(tx==3)||(ty>5)||(ty==3)) err(gcmper);
if((tx<=2)&&(ty<=2)) return mpcmp(x,y);
else
{
avmacourant=avma;f=gsigne(gsub(x,y));
avma=avmacourant;return f;
}
}
long lexcmp(x,y)
GEN x,y;
{
long tx=typ(x),ty=typ(y),lx,ly,fl,s,i;
GEN p1;
if(tx>ty) {p1=x;x=y;y=p1;fl=tx;tx=ty;ty=fl;s= -1;} else s=1;
ly=lg(y);
if(tx<17)
{
if(ty<17) return s*gcmp(x,y);
if(ly==1) return s;
fl=lexcmp(x,y[1]);if(fl) return s*fl;
return (ly>2)?-s:0;
}
lx=lg(x);
if(ly==1) return (lx==1)?0:s;
if(lx==1) return -s;
if((ty==19)&&(tx<19))
{
fl=lexcmp(x,y[1]);if(fl) return s*fl;
return (ly>2)?-s:0;
}
if(lx>ly) {p1=x;x=y;y=p1;fl=lx;lx=ly;ly=fl;s= -s;}
fl=0;for(i=1;(i<lx)&&(!fl);i++) fl=lexcmp(x[i],y[i]);
if(fl) return s*fl;
return (ly>lx)?-s:0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* EGALITE */
/* */
/* Renvoie 1 si x=y, 0 sinon */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
long gegal(x,y)
GEN x,y;
{
long avmacourant,f,i,tx=typ(x),ty=typ(y),lx,masq=0xff00ffff;
GEN p1;
if(tx!=ty)
{
avmacourant=avma;p1=gsub(x,y);f=gcmp0(p1);avma=avmacourant;
}
else
{
switch(tx)
{
case 1: if((x[1]&masq)!=(y[1]&masq)) return 0;
i=2;lx=lgef(x);while((i<lx)&&(x[i]==y[i])) i++;return i==lx;
case 10: if(x[1]!=y[1]) return 0;
i=2;lx=lgef(x);while((i<lx)&&(gegal(x[i],y[i]))) i++;return i==lx;
case 3:
case 6:
case 9: return gegal(x[1],y[1])&&gegal(x[2],y[2]);
case 8: return gegal(x[1],y[1])&&gegal(x[2],y[2])&&gegal(x[3],y[3]);
case 4:
case 5:
case 13:
case 14: avmacourant=avma;f=gegal(gmul(x[1],y[2]),gmul(x[2],y[1]));
avma=avmacourant;return f;
default: avmacourant=avma;p1=gsub(x,y);f=gcmp0(p1);avma=avmacourant;
}
}
return f;
}
long polegal(x,y)
GEN x,y;
/* a usage interne donc pas de verification de types */
{
long i;
if (x[1] != y[1]) return 0;
for(i = lgef(x) - 1; i > 1; i--) if (!gegal(x[i],y[i])) return 0;
return 1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* VALUATION */
/* */
/* renvoie le plus grand exposant de p divisant x quand cela a */
/* un sens (erreur pour les types reels, integermod et polymod */
/* si le module n'est pas divisible par p, et q-adiques pour */
/* q!=p. p doit etre de type entier ou polynome. */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
long ggval(x,p)
GEN x,p;
{
long tx=typ(x),tp=typ(p),lx,i,j,vx,v,av,val,limite=(avma + bot) / 2, tetpil;
GEN p1,p2,reste;
if(isexactzero(x)) err(gvaler2);
if((tx<9)&&(tp==10)) return 0;
switch(tx)
{
case 1: if(tp!=1) err(gvaler4);
val=0;av=avma;
while (1)
{
p1=dvmdii(x,p,&reste);
if (signe(reste)) break;
val++;x=p1;
if (avma < limite)
{
tetpil = avma;
x = gerepile(av, tetpil, gcopy(x));
}
}
avma=av;break;
case 3: p1=cgeti(lgef(x[1]));
if((tp!=1)||(!mpdivis(x[1],p,p1))) err(gvaler4);
p2=cgeti(lgef(x[2]));
if(mpdivis(x[2],p,p2))
{val=1;while(mpdivis(p1,p,p1)&&mpdivis(p2,p,p2)) val++;}
else val=0;
break;
case 7: if((tp!=1)||(!gegal(p,x[2]))) err(gvaler4);
val=valp(x);break;
case 9: if(tp==1) val=ggval(x[2],p);
else
{
if((tp!=10)||(!poldivis(x[1],p,p1))) err(gvaler4);
if(poldivis(x[2],p,p2))
{val=1;while(poldivis(p1,p,p1)&&poldivis(p2,p,p2)) val++;}
else val=0;
}
break;
case 10: i=2;while (isexactzero(x[i])) i++;
if(tp==10)
{
v=varn(p);vx=varn(x);if(vx>v) return 0;
if(vx==v)
{
if(ismonome(p)) val=i-2;
else
{
val=0;av=avma;
while (1)
{
p1=poldivres(x,p,&reste);
if (signe(reste)) break;
val++;x=p1;
if (avma < limite)
{
tetpil = avma;
x = gerepile(av, tetpil, gcopy(x));
}
}
avma=av;
}
}
else
{
val=ggval(x[i],p);
for(j=i+1;j<lgef(x);j++)
if(!gcmp0(x[j])) val=min(val,ggval(x[j],p));
}
}
else
{
if(tp!=1) err(gvaler4);
val=ggval(x[i],p);
for(j=i+1;j<lgef(x);j++)
if(!gcmp0(x[j])) val=min(val,ggval(x[j],p));
}
break;
case 11: if((tp!=10)&&(tp!=11)&&(tp!=1)) err(gvaler4);
v=gvar(p);vx=varn(x);if(vx>v) return 0;
if(vx==v) return (long)(valp(x)/ggval(p,polx[v]));
val=ggval(x[2],p);
for(j=3;j<lg(x);j++)
if(!gcmp0(x[j])) val=min(val,ggval(x[j],p));
break;
case 4:
case 5:
case 13:
case 14: val=ggval(x[1],p)-ggval(x[2],p);break;
case 2:
case 15:
case 16: err(gvaler4);
case 6:
case 8:
case 17:
case 18:
case 19: val=VERYBIGINT;lx=lg(x);
for(j=1;j<lx;j++) val=min(val,ggval(x[j],p));
break;
default: err(gvaler4);
}
return val;
}
pvaluation(x,p,py)
GEN x,p,*py;
{
long l,tetpil,val,limite = (bot + avma) / 2;
GEN p1,reste;
val=0;*py=cgeti(lgef(x));l=avma;
while (1)
{
p1=dvmdii(x,p,&reste);
if (signe(reste)) break;
val++;x=p1;
if (avma < limite)
{
tetpil = avma;
x = gerepile(l, tetpil, gcopy(x));
}
}
affii(x,*py);avma=l;
return val;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* NEGATION */
/* */
/* Cree-x,ou x pointe sur un GEN . */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN gneg(x)
GEN x;
{
long tx,lx,i,sx;
GEN y;
if (gcmp0(x))
{
y=gcopy(x);
}
else
{
tx=typ(x);lx=lg(x);
switch(tx)
{
case 1 :
case 2 : y=gcopy(x);
sx=signe(x);
sx= -sx;
setsigne(y,sx);
break;
case 3 : y=cgetg(3,tx);y[1]=copyifstack(x[1]);
if(gcmp0(x[2])) y[2]=zero;
else
y[2]=lsubii(y[1],x[2]);
break;
case 9: y=cgetg(3,tx);y[1]=copyifstack(x[1]);
y[2]=lneg(x[2]);
break;
case 4 :
case 5 :
case 13:
case 14: y=cgetg(3,tx);y[1]=lneg(x[1]);y[2]=lcopy(x[2]);
break;
case 7 : y=cgetp(x);
if(gcmp0(x[4])) {affsi(0,y[4]);y[1]=x[1];}
else
{
subiiz(y[3],x[4],y[4]);
setvalp(y,valp(x));
}
break;
case 8 : y=cgetg(lx,tx);
for (i=2;i<lx;i++) y[i]=lneg(x[i]);
y[1]=copyifstack(x[1]);
break;
case 6 :
case 17:
case 18:
case 19: y=cgetg(lx,tx);
for (i=1;i<lx;i++) y[i]=lneg(x[i]);
break;
case 15:
case 16: err(gneger);
case 10: lx=lgef(x);
y=cgetg(lx,tx);
for (i=2;i<lx;i++) y[i]=lneg(x[i]);
y[1]=x[1];
break;
case 11: y=cgetg(lx,tx);
for (i=2;i<lx;i++) y[i]=lneg(x[i]);
y[1]=x[1];
}
}
return y;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* VALEUR ABSOLUE */
/* */
/* Cree un GEN pointant sur la valeur absolue de x */
/* a condition que x soit un entier,ou un reel, */
/* ou une fraction,ou un complexe;sinon erreur . */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN gabs(x,prec)
GEN x;
{
long tx=typ(x),lx=lg(x),i,l,tetpil;
GEN y,p1;
switch(tx)
{
case 1 :
case 2 : y=mpabs(x);break;
case 4 :
case 5 : y=cgetg(lx,tx);
y[1]=lmpabs(x[1]);
y[2]=lmpabs(x[2]);
break;
case 6 : l=avma;p1=gnorm(x);tetpil=avma;
y=gsqrt(p1,prec);y=gerepile(l,tetpil,y);
break;
case 8 : y=transc(gabs,x,prec);break;
case 17:
case 18:
case 19: y=cgetg(lx,tx);
for(i=1;i<lx;i++)
y[i]=labs(x[i]);
break;
default: err(gabser);
}
return y;
}
GEN gmax(x,y)
GEN x,y;
{
return (gcmp(x,y)>=0) ? gcopy(x) : gcopy(y);
}
GEN gmin(x,y)
GEN x,y;
{
return (gcmp(x,y)<=0) ? gcopy(x) : gcopy(y);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* AFFECTATION S--> GEN */
/* */
/* Etant donnes un long et un GEN,affecte le long */
/* dans le GEN,permettant une initialisation . */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void gaffsg(s,x)
long s;
GEN x;
{
long tx,l,i,v,val;
GEN reste,p1;
tx=typ(x);
switch(tx)
{
case 1 : affsi(s,x);break;
case 2 : affsr(s,x);break;
case 3 : modsiz(s,x[1],x[2]);break;
case 4 :
case 5 : affsi(s,x[1]);
affsi(1,x[2]);
break;
case 6 : gaffsg(s,x[1]);
gaffsg(0,x[2]);
break;
case 7 : if (!s) {setvalp(x,defaultpadicprecision);x[4]=zero;}
else
{
val=0;
l=avma;
while (1)
{
p1=dvmdsi(s,x[2],&reste);
if (signe(reste)) break;
val++;s=itos(p1);
}
avma=l;
setvalp(x,val);
if (s>0) affsi(s,x[4]);
else addsiz(s,x[3],x[4]);
}
break;
case 8 : gaffsg(s,x[2]);
gaffsg(0,x[3]);
break;
case 9 : gaffsg(s,x[2]);break;
case 10: v=varn(x);
if (!s) x[1]=2;
else
{
x[1]=0x1000003;gaffsg(s,x[2]);
}
setvarn(x,v);break;
case 11: v=varn(x);gaffsg(s,x[2]);l=lg(x);
if (!s) x[1]=0x7ffe +l;
else
{
x[1]=0x1008000;
for (i=3;i<l;gaffsg(0,x[i]),i++);
}
setvarn(x,v);break;
case 13:
case 14: gaffsg(s,x[1]);gaffsg(1,x[2]);
break;
case 17:
case 18: if (lg(x)!=2) err(gaffsger1);
else gaffsg(s,x[1]);break;
case 19: if (lg(x)!=2) err(gaffsger2);
else gaffsg(s,x[1]);break;
default: err(gaffer1);
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* AFFECTATION GENERALE */
/* */
/* Etant donnes deux GEN x et y,affecte le contenu */
/* de x dans y,si cela est possible . */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void gaffect(x,y)
GEN x,y;
{
long i,j,k,l,v,vy,val,lx,ly,tx,ty,d,avmacourant;
long num,den;
GEN p1;
tx=typ(x);ty=typ(y);lx=lg(x);ly=lg(y);
if (tx<10)
{
if (ty>=10)
{
switch(ty)
{
case 10: v=varn(y);gaffect(x,y[2]);
for(i=3;i<ly;gaffsg(0,y[i]),i++);
if (gcmp0(x)) y[1]=2;
else y[1]=0x1000003;
setvarn(y,v);break;
case 11: v=varn(y);gaffect(x,y[2]);
if (gcmp0(x)) y[1]=0x7ffe +ly;
else
{
y[1]=0x1008000;
for (i=3;i<ly;gaffsg(0,y[i]),i++);
}
setvarn(y,v);break;
case 13:
case 14: gaffect(x,y[1]);gaffsg(1,y[2]); break;
case 17:
case 18:
case 19: err(gaffer2);
default: err(gaffer1);
}
}
else
{
switch(tx)
{
case 1 :
switch(ty)
{
case 1 : affii(x,y);break;
case 2 : affir(x,y);break;
case 3 : modiiz(x,y[1],y[2]);break;
case 4 :
case 5 : affii(x,y[1]);affsi(1,y[2]); break;
case 6 : gaffect(x,y[1]);gaffsg(0,y[2]); break;
case 7 : if (!signe(x)) {setvalp(y,defaultpadicprecision);y[4]=zero;}
else
{
l=avma;
val=pvaluation(x,y[2],&p1);
setvalp(y,val);modiiz(p1,y[3],y[4]);
avma=l;
}
break;
case 8 : gaffect(x,y[2]);gaffsg(0,y[3]); break;
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 2 :
switch(ty)
{
case 1 : err(gaffer3);
case 2 : affrr(x,y);break;
case 3 :
case 4 :
case 5 : err(gaffer3);
case 6 : gaffect(x,y[1]);gaffsg(0,y[2]); break;
case 7 :
case 8 : err(gaffer3);
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 3 :
switch(ty)
{
case 1 :
case 2 : err(gaffer4);
case 3 : if (!divise(x[1],y[1])) err(gaffer5);
modiiz(x[2],y[1],y[2]); break;
case 4 :
case 5 :
case 6 :
case 8 : err(gaffer4);
case 7 : err(gaffer6);
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 4 :
switch(ty)
{
case 1 : i=mpdivis(x[1],x[2],y);
if (!i) err(gaffer7);
break;
case 2 : diviiz(x[1],x[2],y);break;
case 3 : avmacourant=avma;
p1=mpinvmod(x[2],y[1]);
modiiz(mulii(x[1],p1),y[1],y[2]);
avma=avmacourant;
break;
case 4 :
case 5 : for (i=1;i<=2;affii(x[i],y[i]),i++);break;
case 6 : gaffect(x,y[1]);gaffsg(0,y[2]); break;
case 7 : if(!signe(x[1]))
{
setvalp(y,defaultpadicprecision);y[4]=zero;
}
else
{
l=avma;num=x[1];den=x[2];
if(!(val=pvaluation(num,y[2],&num)))
val= -pvaluation(den,y[2],&den);
p1=mulii(num,mpinvmod(den,y[3]));
modiiz(p1,y[3],y[4]);avma=l;
setvalp(y,val);
}
break;
case 8 : gaffect(x,y[2]);gaffsg(0,y[3]); break;
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 5 :
switch(ty)
{
case 1 : i=mpdivis(x[1],x[2],y);
if (!i) err(gaffer7);
break;
case 2 : diviiz(x[1],x[2],y);break;
case 3 : avmacourant=avma;gaffect(gred(x),y);
avma=avmacourant;
break;
case 4 : gredz(x,y);break;
case 5 : for (i=1;i<=2;affii(x[i],y[i]),i++);break;
case 6 : gaffect(x,y[1]);gaffsg(0,y[2]); break;
case 7 : if(!signe(x[1]))
{
setvalp(y,defaultpadicprecision);y[4]=zero;
}
else
{
l=avma;num=x[1];den=x[2];
val=pvaluation(num,y[2],&num)-pvaluation(den,y[2],&den);
p1=mulii(num,mpinvmod(den,y[3]));
modiiz(p1,y[3],y[4]);avma=l;
setvalp(y,val);
}
break;
case 8 : gaffect(x,y[2]);gaffsg(0,y[3]); break;
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 6 :
switch(ty)
{
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 7 :
case 8 : if (!gcmp0(x[2])) err(gaffer8);
gaffect(x[1],y);
break;
case 6 : for (i=1;i<=2;gaffect(x[i],y[i]),i++);break;
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 7 :
switch(ty)
{
case 1 :
case 2 : err(gaffer10);
case 3 : if(valp(x)<0) err(gaffer11);
l=avma;
val=pvaluation(y[1],x[2],&p1);
if(!gcmp1(p1)) err(gaffer11);
if(val>(signe(x[4])?(precp(x)+valp(x)):valp(x)+1)) err(gaffer11);
modiiz(x[4],y[1],y[2]);
avma=l;break;
case 4 :
case 5 :
case 6 :
case 8 : err(gaffer10);
case 7 : if(cmpii(x[2],y[2])) err(gaffer12);
modiiz(x[4],y[3],y[4]);
setvalp(y,valp (x));
break;
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 8 :
switch(ty)
{
case 1 :
case 3 :
case 4 :
case 5 :
case 7 : if(!gcmp0(x[3])) err(gaffer9);
gaffect(x[2],y);
break;
case 2 : l=avma;p1=co8(x,ly);gaffect(p1,y);
avma=l;break;
case 6 : ly=precision(y);
if(ly)
{
l=avma;p1=co8(x,ly);gaffect(p1,y);
avma=l;
}
else
{
if(!gcmp0(x[3])) err(gaffer9);
gaffect(x[2],y);
}
break;
case 8 : if(!gegal(x[1],y[1])) err(gaffer21);
for (i=2;i<=3;gaffect(x[i],y[i]),i++);
break;
case 9 : gaffect(x,y[2]);break;
default: err(gaffer1);
}
break;
case 9 : if(ty!=9) err(gaffer17);
if (gdivise(x[1],y[1]))
gmodz(x[2],y[1],y[2]);else err(gaffer18);
break;
default: err(gaffer1);
}
}
}
else
{
if (ty<9) err(gaffer13);
switch(tx)
{
case 10: v=varn(x);
switch(ty)
{
case 10: if((vy=varn(y))>v) err(gaffer13);
if(vy==v)
{
d=lgef(x);
if (d>ly) err(gaffer14);
y[1]=x[1];
for (i=2;i<d;gaffect(x[i],y[i]),i++);
}
else
{
gaffect(x,y[2]);
for(i=3;i<ly;gaffsg(0,y[i]),i++);
if (signe(x)) y[1]=0x1000003;
else y[1]=2;
setvarn(y,vy);
}
break;
case 11: if((vy=varn(y))>v) err(gaffer13);
if (!signe(x)) gaffsg(0,y);
else
{
if(vy==v)
{
i=gval(x,v);setvalp(y,i);setsigne(y,1);
k=lgef(x)-i;
if(k>ly) k=ly;
for (j=2;j<k;j++)
gaffect(x[i+j],y[j]);
for (j=k;j<ly;j++)
gaffsg(0,y[j]);
}
else
{
gaffect(x,y[2]);
if (!signe(x)) y[1]=0x7ffe +ly;
else
{
y[1]=0x1008000;
for (i=3;i<ly;gaffsg(0,y[i]),i++);
}
setvarn(y,vy);
}
}
break;
case 9: gmodz(x,y[1],y[2]);break;
case 13:
case 14: gaffect(x,y[1]);gaffsg(1,y[2]); break;
case 17:
case 18:
case 19: err(gaffer15);
default: err(gaffer1);
}
break;
case 11: if (ty!=11) err(gaffer16);
v=varn(x);if((vy=varn(y))>v) err(gaffer13);
if(vy==v)
{
y[1]=x[1];
if(!gcmp0(x))
{
k=lx;if (k>ly) k=ly;
for (i=2;i<k;i++) gaffect(x[i],y[i]);
for (i=k;i<ly;i++) gaffsg(0,y[i]);
}
}
else
{
gaffect(x,y[2]);
if (!signe(x)) y[1]=0x7ffe +ly;
else
{
y[1]=0x1008000;
for (i=3;i<ly;gaffsg(0,y[i]),i++);
}
setvarn(y,vy);
}
break;
case 13:
case 14: switch(ty)
{
case 10:
case 17:
case 18:
case 19: err(gaffer19);
case 11: gdivz(x[1],x[2],y);break;
case 9: avmacourant=avma;p1=ginvmod(x[2],y[1]);
gmod(gmul(x[1],p1),y[1],y[2]);
avma=avmacourant;
break;
case 13:
if (tx==14) gredz(x,y);
else
for (i=1;i<=2;gaffect(x[i],y[i]),i++);
break;
case 14: for (i=1;i<=2;gaffect(x[i],y[i]),i++); break;
default: err(gaffer1);
}
break;
case 15:
case 16:
case 17:
case 18:
case 19: if (ty!=tx) err(gaffer20);
if (ly!=lx) err(gaffer20);
for (i=1;i<lx;gaffect(x[i],y[i]),i++);
break;
default: err(gaffer1);
}
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* CONVERSION QUAD-->REEL,COMPLEXE */
/* OU P-ADIQUE */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN co8(x,l)
GEN x;
long l;
{
long av,tetpil;
GEN y,p1,p2,p3;
p3=(GEN)x[1];
av=avma;p1=gmul2n(p3[3],-1);
p2=gsqrt(gsub(gmul(p1,p1),p3[2]),l);
p1=gmul(x[3],gsub(p2,p1));
tetpil=avma;y=gerepile(av,tetpil,gadd(p1,x[2]));
return y;
}
GEN cvtop(x,p,l)
GEN x,p;
long l;
{
GEN z,p1,p2,p3;
long av,tetpil,n,tx=typ(x);
if(typ(p)!=1) err(cvtoper1);
if(gcmp0(x)) z=ggrando(p,l);
else
{
switch(tx)
{
case 1: z=gadd(x,ggrando(p,ggval(x,p)+l));break;
case 2: err(cvtoper2);
case 3: n=ggval(x[1],p);
if(n>l) n=l;
z=gadd(x[2],ggrando(p,n));break;
case 4:
case 5: n=ggval(x[1],p);
n-=ggval(x[2],p);
z=gadd(x,ggrando(p,n+l));break;
case 6: av=avma;p1=gsqrt(gaddgs(ggrando(p,l),-1));
p1=gmul(p1,x[2]);tetpil=avma;
z=gerepile(av,tetpil,gadd(p1,x[1]));
break;
case 7: z=gprec(x,l);break;
case 8:
av=avma;p1=(GEN)x[1];p3=gmul2n(p1[3],-1);
p2=gsub(gmul(p3,p3),p1[2]);
switch(typ(p2))
{
case 1: n=ggval(p2,p);
p2=gadd(p2,ggrando(p,n+l));break;
case 3: break;
case 4:
case 5: n=ggval(p2[1],p);
n-=ggval(p2[2],p);
p2=gadd(p2,ggrando(p,n+l));break;
case 7: break;
default: err(gadder14);
}
p2=gsqrt(p2);
p1=gmul(x[3],gsub(p2,p3));tetpil=avma;
z=gerepile(av,tetpil,gadd(x[2],p1));
break;
default: err(cvtoper2);
}
}
return z;
}
GEN gcvtop(x,p,r)
GEN x,p;
long r;
{
long i,tx=typ(x),lx;
GEN y;
if(tx<9) return cvtop(x,p,r);
switch(tx)
{
case 10: lx=lgef(x);y=cgetg(lx,10);y[1]=x[1];
for(i=2;i<lx;i++) y[i]=(long)gcvtop(x[i],p,r);break;
case 11:
if(gcmp0(x)) y=gcopy(x);
else
{
lx=lg(x);y[1]=x[1];
for(i=2;i<lx;i++) y[i]=(long)gcvtop(x[i],p,r);
}
break;
case 9:
case 13:
case 14:
case 17:
case 18:
case 19: lx=lg(x);y=cgetg(lx,tx);
for(i=1;i<lx;i++) y[i]=(long)gcvtop(x[i]);break;
default: err(cvtoper2);
}
return y;
}
long gexpo(x)
GEN x;
{
long tx=typ(x),lx=lg(x),e,i,y,av;
GEN p1;
switch(tx)
{
case 1 :if(!signe(x)) err(gexpoer2);
return expi(x);
case 4 :
case 5 : if(!signe(x[1])) err(gexpoer2);
return expi(x[1])-expi(x[2]);
case 2 : return expo(x);
case 6 : av=avma;p1=gnorm(x);y=(gexpo(p1)>>1); avma=av;break;
case 8 : if(gcmp0(x)) err(gexpoer2);
av=avma;p1=cgetg(3,6);p1[1]=lgetr(3);
p1[2]=lgetr(3);gaffect(x,p1);y=gexpo(p1);
avma=av;break;
case 10: lx=lgef(x);
case 11:
case 17:
case 18:
case 19: y= -BIGINT;
for(i=lontyp[tx];i<lx;i++)
{
e=gexpo(x[i]);if(e>y) y=e;
}
break;
default: err(gexpoer1);
}
return y;
}
long gsize(x)
GEN x;
{
long l;
if(gcmp0(x)) return 0;
l=gexpo(x)*L2SL10;
return l;
}
void normalize(px)
GEN *px;
{
long i,j,v,l,tetpil,e,lx,f;
GEN p1,x;
if(typ(x= *px)!=11) err(gnormaler);
i=2;f=1;lx=lg(x);v=varn(x);
while (f&&(i<lx))
{f=isexactzero(x[i]);i++;}
/* {f=gcmp0(x[i]);i++;} */
i--;
if(i>2)
{
l=(long)(x+lx);e=valp(x);
if (f)
{
avma=l;
p1=cgetg(3,11);p1[1]=0x7ffe +lx;
*px=p1;
}
else
{
tetpil=avma;
p1=cgetg(lx-i+2,11);
p1[1]=0x1007ffe +e+i;
for (j=i;j<lx;j++)
p1[j-i+2]=lcopy(x[j]);
*px=gerepile(l,tetpil,p1);
}
setvarn(*px,v);
}
else
{
if(f) setsigne(x,0);else setsigne(x,1);
}
}
void normalizepol(px)
GEN *px;
{
long i,lx,f;
GEN x;
if(typ(x= *px)!=10) err(gnormaler);
lx=lgef(x);
if(lx>2)
{
f=1;i=lx-1;
while (f&&(i>1))
{f=isexactzero(x[i]);i--;}
if(f) {setlgef(*px,2);setsigne(*px,0);}
else
{
i++;f=gcmp0(x[i]);setlgef(*px,i+1);
while(f&&(i>1))
{f=gcmp0(x[i]);i--;}
setsigne(*px,f?0:1);
}
}
else setsigne(*px,0);
}
long gsigne(x)
GEN x;
{
switch(typ(x))
{
case 1:
case 2: return signe(x);
case 4:
case 5: return (signe(x[2])>0) ? signe(x[1]) : -signe(x[1]);
default: err(gsigner);
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* */
/* PUISSANCE */
/* */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
GEN gpui(x,n,prec)
GEN x,n;
long prec;
{
long av1,av2,av3,lx,tx,i,j,tetpil;
unsigned long m;
GEN p1,p2,y,z,alp;
if (typ(n)==1)
{
if((lgef(n)<=3)&&cmpis(n,0x7fffffff)<0) y=gpuigs(x,itos(n),prec);
else
{
z=x;av1=avma;
if((typ(x)!=16)&&(typ(x)!=15)) y=gun;
else
{
if(typ(x)==16)
{
p1=mulii(x[1],x[3]);p2=shifti(mulii(x[2],x[2]),-2);
y=cgetg(4,16);y[1]=un;y[2]=mpodd(x[2]) ? un : zero;
y[3]=lsubii(p1,p2);
}
else
{
y=cgetg(5,15);y[1]=un;
p1=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2));
p2=racine(p1);if(mpodd(subii(p2,x[2]))) p2=addsi(-1,p2);
y[2]=(long)p2;y[3]=lshifti(subii(mulii(p2,p2),p1),-2);
p1=cgetr(prec);y[4]=(long)p1;p1[1]=0x800000-((prec-2)<<5);
p1[2]=0;tetpil=avma;y=gerepile(av1,tetpil,gcopy(y));
}
}
for (i=lgef(n)-1;i>2;i--)
{
for (m=n[i],j=0;j<32;j++,m>>=1)
{
if (m&1) y=gmul(y,z);
z=gsqr(z);
}
}
for (m=n[2];m>1;m>>=1)
{
if (m&1) y=gmul(y,z);
z=gsqr(z);
}
if (signe(n)>0)
{
tetpil=avma;y=gmul(y,z);
}
else
{
y=gmul(y,z);
tetpil=avma;y=ginv(y);
}
y=gerepile(av1,tetpil,y);
}
}
else
{
if((tx=typ(x))>=17)
{
y=cgetg(lx=lg(x),tx);for(i=1;i<lx;i++) y[i]=lpui(x[i],n,prec);
}
else
{
if(tx!=11)
{
av1=avma;
if(gcmp0(x))
{
if(gcmpgs(p1=greal(n),0)<=0) err(gpuier3);
av2=precision(x);
if(av2)
{
p1=ground(gmulsg(gexpo(x),p1));
if(lgef(p1)>3) err(gpuier4);
av2=itos(p1);if(abs(av2)>=0x800000) err(gpuier4);
avma=av1;y=cgetr(3);y[2]=0;y[1]=0x800000+av2;
}
else {avma=av1;y=gcopy(x);}
}
else
{
y=gmul(n,glog(x,prec));av2=avma;
y=gerepile(av1,av2,gexp(y,prec));
}
}
else
{
if(valp(x)) err(gpuier2);
if(gvar9(n)>varn(x))
{
if(gcmp1(x[2]))
{
av1=avma;alp=gaddgs(n,1);
av2=avma;y=cgetg(lx=lg(x),11);y[1]=0x1008000;
y[2]=un;setvarn(y,varn(x));
for(i=3;i<lx;i++)
{
av3=avma;p1=gzero;
for(j=1;j<i-1;j++)
{
p2=gsubgs(gmulgs(alp,j),i-2);
p1=gadd(p1,gmul(gmul(p2,x[j+2]),y[i-j]));
}
tetpil=avma;
y[i]=lpile(av3,tetpil,gdivgs(p1,i-2));
}
y=gerepile(av1,av2,y);
}
else
{
av1=avma;p1=gdiv(x,x[2]);
p1=gpui(p1,n,prec);p2=gpui(x[2],n,prec);
tetpil=avma;y=gerepile(av1,tetpil,gmul(p1,p2));
}
}
else
{
y=gmul(n,glog(x,prec));av2=avma;
y=gerepile(av1,av2,gexp(y,prec));
}
}
}
}
return y;
}
GEN gpuigs(x,n,prec)
GEN x;
long n,prec;
{
long lx,av,m,dd,tetpil,i,j;
GEN y,z,p1,p2;
if (!n)
{
lx=lg(x);
switch(typ(x))
{
case 1 :
case 2 :
case 4 :
case 5 : y=gun;break;
case 6 : y=cgetg(3,6);y[1]=un;
y[2]=zero;
break;
case 3 : y=cgetg(3,3);y[1]=copyifstack(x[1]);
y[2]=un;
break;
case 8 : y=cgetg(4,8);y[1]=copyifstack(x[1]);
y[2]=un;y[3]=zero;
break;
case 10:
case 11:
case 13:
case 14: y=polun[varn(x)]; break;
case 9: y=cgetg(3,9);y[1]=copyifstack(x[1]);
y[2]=lpuigs(x[2],0);
break;
case 15 : av=avma;y=cgetg(5,15);y[1]=un;
p1=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2));
p2=racine(p1);if(mpodd(subii(p2,x[2]))) p2=addsi(-1,p2);
y[2]=(long)p2;y[3]=lshifti(subii(mulii(p2,p2),p1),-2);
p1=cgetr(prec);y[4]=(long)p1;p1[1]=0x800000-((prec-2)<<5);
p1[2]=0;tetpil=avma;y=gerepile(av,tetpil,gcopy(y));break;
case 16 : y=cgetg(4,16);y[1]=un;y[2]=mpodd(x[2]) ? un : zero;
av=avma;p1=mulii(x[1],x[3]);p2=shifti(mulii(x[2],x[2]),-2);tetpil=avma;
y[3]=lpile(av,tetpil,subii(p1,p2));break;
case 17:
case 18: err(gpuier1);
case 19: if (lx!=(lg(x[1]))) err(gpuier1);
else
{
y=cgetg(lx,19);
for (j=1;j<lx;j++)
{
y[j]=lgetg(lx,18);
for (i=1;i<lx;i++)
coeff(y,i,j)=(i!=j) ? zero :
lpuigs(coeff(x,i,i),0);
}
}
}
}
else if (n==1) y=gcopy(x);
else if (n== -1) y=ginv(x);
else
{
m=abs(n);
if(ismonome(x))
{
j=lgef(x);
dd=(j-3)*m+3;
av=avma;p1=cgetg(dd,10);p1[1]=0x1000000+dd;setvarn(p1,varn(x));
p1[dd-1]=lpuigs(x[j-1],m);
for(i=2;i<dd-1;i++) p1[i]=zero;
if(n<0)
{
tetpil=avma;y=cgetg(3,13);y[1]=(long)denom(p1[dd-1]);
y[2]=lmul(p1,y[1]);y=gerepile(av,tetpil,y);
}
else y=p1;
}
else
{
z=x;av=avma;
if((typ(x)!=16)&&(typ(x)!=15)) y=gun;
else
{
if(typ(x)==16)
{
p1=mulii(x[1],x[3]);p2=shifti(mulii(x[2],x[2]),-2);
y=cgetg(4,16);y[1]=un;if(mpodd(x[2])) y[2]=un;else y[2]=zero;
y[3]=lsubii(p1,p2);
}
else
{
y=cgetg(5,15);y[1]=un;
p1=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2));
p2=racine(p1);if(mpodd(subii(p2,x[2]))) p2=addsi(-1,p2);
y[2]=(long)p2;y[3]=lshifti(subii(mulii(p2,p2),p1),-2);
p1=cgetr(prec);y[4]=(long)p1;p1[1]=0x800000-((prec-2)<<5);
p1[2]=0;tetpil=avma;y=gerepile(av,tetpil,gcopy(y));
}
}
for(;m>1;m>>=1)
{
if (m&1) y=gmul(y,z);
z=gsqr(z);
}
if (n>0)
{
tetpil=avma;y=gmul(y,z);
}
else
{
y=gmul(y,z);
tetpil=avma;y=ginv(y);
}
y=gerepile(av,tetpil,y);
}
}
return y;
}
long iscomplex(x)
GEN x;
{
long tx=typ(x);
switch(tx)
{
case 1:
case 2:
case 4:
case 5: return 0;
case 6: return !gcmp0(x[2]);
case 8: return signe(((GEN)x[1])[2])>0;
default: err(iscomplexer1);
}
}
long ismonome(x)
GEN x;
{
long i,l;
if((typ(x)!=10)||(!signe(x))) return 0;
l=lgef(x)-1;i=2;
while((i<=l)&&isexactzero(x[i])) i++;
return i==l;
}
GEN gsqr(x)
GEN x;
{
long tx=typ(x),lx,av,i,j;
GEN y,p1;
if(tx==7)
{
y=cgetg(5,7);
y[2]=x[2];
if(!cmpis(x[2] ,2))
{
i=precp(x)+1;av=avma;
p1=addii(x[3],shifti(x[4],1));
if(!gcmp0(p1))
{
j=vali(p1);if(j<i) i=j;
}
avma=av;y[3]=lshifti(x[3],i);
setprecp(y,precp(x)+i);
}
else
{
y[3]=lcopy(x[3]);
setprecp(y,precp(x));
}
y[4]=lgeti(lg(y[3]));
setvalp(y,2*valp(x));av=avma;
modiiz(mulii(x[4],x[4]),y[3],y[4]);
avma=av;
}
else if(tx==15) y=sqcompreal(x);
else if(tx==16) y=sqcomp(x);
else
{
if((tx<17)||((tx==19)&&(lg(x)==lg(x[1])))) y=gmul(x,x);
else
{
y=cgetg(lx=lg(x),tx);
for(i=1;i<lx;i++)
y[i]=lsqr(x[i]);
}
}
return y;
}